package org.wattdepot.cli.command;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.property.jaxb.Property;
import org.wattdepot.resource.sensordata.jaxb.SensorData;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Used to get the SensorData for a source for an entire day.
 * 
 * @author Kimberly Heu, Kendyll Doi
 */
public class WattSensorDataDay {
  
  /**
   * Gets the SensorData for a source for an entire day.
   * 
   * @param sourceName The name of the source.
   * @param day The date to get the data for.
   * @param client The WattDepot client used.
   * @return A String containing all of the data for the source.
   */
  public static String wattSensorDataDay(String sourceName, String day, WattDepotClient client) {
    // Messages to be displayed in the case of an error
    String resourceNotFoundMessage = "No data found for ";
    String miscClientMessage = "Error while retrieving resource";
    String notAuthorizedMessage = "Not authorized to retrieve information.";
    String badXmlMessage = "Error enountered getting information from server.";
    
    String output = null; // Output string
    StringBuffer buf = new StringBuffer(5000); // Buffer for output text
    XMLGregorianCalendar startTime; // Start time for data gathering
    XMLGregorianCalendar endTime; // End time for data gathering
    List<SensorData> sensorDataList; // List of all data points
    
    try {
      // Initialize the start and end times
      startTime = Tstamp.makeTimestamp(day);
      endTime = Tstamp.incrementDays(startTime, 1);
      endTime = Tstamp.incrementMilliseconds(endTime, -1);
      
      // Get all of the data on the source between the two times.
      sensorDataList = client.getSensorDatas(sourceName, startTime, endTime);
      
      // If no data exists, let the user know
      if (sensorDataList.isEmpty()) {
        buf.append("No data found for " + sourceName + "\n");
      }
      
      // For each of the data points, print out information
      for (SensorData sensorData : sensorDataList) {
        buf.append("\n" + sensorData.getTimestamp() + "\n\t" + "Tool: " + sensorData.getTool());
        buf.append("\n\t" + "Properties: ");
        for (Property property : sensorData.getProperties().getProperty()) {
          buf.append("\t\t (" + property.getKey() + " : " + property.getValue() + ")");
        }
      }
    }
    catch (ResourceNotFoundException e) {
      // Occurs if source does not exist
      buf.append(resourceNotFoundMessage);
      buf.append(sourceName);
    }
    catch (MiscClientException e) {
      // Occurs if error happens while getting data
      buf.append(miscClientMessage);
    }
    catch (NotAuthorizedException e) {
      // Occurs if user is not authorized to get information
      buf.append(notAuthorizedMessage);
    }
    catch (BadXmlException e) {
      // Occurs if data is corrupted
      buf.append(badXmlMessage);
    }
    catch (Exception e) {
      // Catch any other errors
      buf.append("Encountered error: ");
      buf.append(e);
    }
    
    // Transfer buffer contents to output string, and return
    output = buf.toString();
    return output;
  }
}
